package com.hxzy.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author wy
 * @Description 服务调用，调用订单服务(SpringCloud  Alibaba内置服务发现操作)
 * @Date 2023/10/12 10:19
 * @Version 1.0
 */
@RestController
public class CallServiceDiscoveryController {


    private RestTemplate  restTemplate=new RestTemplate();

    /**
     * springcloud定义的服务发送客户端的接口
     * 我们使用nacos-discovery.java它自动装配NacosDiscoveryClient类
     * 调用  List<ServiceInstance> getInstances(String serviceId  服务名)
     */
    @Autowired
    private DiscoveryClient  discoveryClient;

    //定义一个全局变量  int
    private AtomicInteger  atomicInteger=new AtomicInteger(0);


    @GetMapping(value = "/call/discovery/order")
    public String callOrderService(){
        Map<String,Object> map=new HashMap<>();
        map.put("productId",1000);
        map.put("num",2);
        map.put("userId",2);
        map.put("shopId",100);

        //1、调用远程服务，它使用json格式接收数据
        HttpHeaders requestHeaders = new HttpHeaders();
        // 重点是配置请求头内容类型为："application/json"
        requestHeaders.setContentType(MediaType.APPLICATION_JSON);


        //使用  负载均衡算法（ 1、轮询   2、随机  3、权重（越高优先提供服务）  4、最短响应时间 。。。。。。   ）
        ServiceInstance serviceInstance = this.randomRobin();
        String api=serviceInstance.getUri().toString();

        //2、定义远程地址 http://192.168.21.100:19000
        String url=api+"/order/create";

        //3、参数和请求参数型包装起来
        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<Map<String, Object>>(map, requestHeaders);

        //4、使用restTemplate发送post请求并得到响应结果

        String data= restTemplate.postForObject(url, requestEntity, String.class);

        return data;
    }

    /**
     * 轮询算法
     * @return
     */
    private ServiceInstance  roundRobin(){
        //调用nacos，向nacos查询可用的服务列表，(再来选择一个，做为本次的服务主机)负载均衡算法
        List<ServiceInstance> instances = this.discoveryClient.getInstances("order-server");
        if(instances.isEmpty()){
            throw new RuntimeException("order-server没有可用服务");
        }
        // 0  1 2 3 4 5 6 7 8 9  .....
        int index = this.atomicInteger.getAndIncrement();
        ServiceInstance serviceInstance = instances.get(  index % instances.size()  );
        return serviceInstance;
    }

    /**
     * 随机算法
     * @return
     */
    private ServiceInstance  randomRobin(){
        //调用nacos，向nacos查询可用的服务列表，(再来选择一个，做为本次的服务主机)负载均衡算法
        List<ServiceInstance> instances = this.discoveryClient.getInstances("order-server");
        if(instances.isEmpty()){
            throw new RuntimeException("order-server没有可用服务");
        }
        Random random=new Random();
        int index=random.nextInt( instances.size());
        ServiceInstance serviceInstance = instances.get(  index % instances.size()  );
        return serviceInstance;
    }

}
